/*
 * Photomanager 0.2
 * http://is-webdesign.com/
 *
 * Copyright (c) 2009 is webdesign sarl
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Date: 24-10-2009
 *
 */

(function($) {
	// jQuery plugin
	$.photomanager = {
		defaults	: {
		    lang: 'fr',
		    source: '',
		    output_width: 415,
		    output_height: 233,
		    background_color: '#333',
		    magnification: 1,
		    host_overflow : '',
			rules	: {
			    output_resizable: true,
			    closable: true
			},
			callback: {
			    onopen: function(INSTANCE) {
			        
			    },
			    onsave: function(INSTANCE, PARAMETERS) {
			        
			    },
			    onloaderror: function(INSTANCE) {
			        
			    }
			},
			plugins : {
			    colorpicker : {
			        css: 'components/farbtastic/farbtastic.css',
			        js: 'components/farbtastic/farbtastic.js'
			    }
			}
		},

		create		: function () { return new photomanager_component(); },
		reference	: function (obj) { 
			var o = $(obj); 
			if(!o.size()) o = $("#" + obj);
			if(!o.size()) return null; 
			o = (o.is(".photomanager")) ? o.attr("id") : o.parents(".photomanager:eq(0)").attr("id"); 
			return photomanager_component.inst[o] || null; 
		}
	};
	$.fn.photomanager = function (opts) {
		return this.each(function() {
			var conf = $.extend({},opts);
			if(photomanager_component.inst && photomanager_component.inst[$(this).attr('id')]) photomanager_component.inst[$(this).attr('id')].destroy();
			if(conf !== false) new photomanager_component().init(this, conf);
		});
	};

	// core
	function photomanager_component () {
		return {
			cntr : ++photomanager_component.cntr,
			settings : $.extend({},$.photomanager.defaults),

			init : function(elem, conf) {
				var _this = this;
				this.container = $(elem);
				if(this.container.size == 0) return false;
				photomanager_component.inst[this.cntr] = this;

                // if(!this.container.attr("id")) this.container.attr("id","jsphotomanager_" + this.cntr); 
                // photomanager_component.inst[this.container.attr("id")] = photomanager_component.inst[this.cntr];
				this.settings = $.extend(true, {}, this.settings, conf);
				
				// create the viewport
                $('\
                    <div class="photomanager" id="photomanager-'+this.cntr+'">\
                        <div class="photomanager-header">\
                            <ul class="photomanager-tools">\
                                <li class="photomanager-tool-information" title="'+this.gettext('Show informations')+'"></li>\
                                <li class="photomanager-tool-colorpicker" title="'+this.gettext('Select background color')+'"></li>\
                                <li class="photomanager-tool-fitbox" title="'+this.gettext('Fit box')+'"></li>\
                                <li class="photomanager-tool-fillbox" title="'+this.gettext('Fill box')+'"></li>\
                                <li class="photomanager-tool-center" title="'+this.gettext('Center')+'"></li>\
                                <li></li>\
                            </ul>\
                            <div class="photomanager-toolbar-close"></div>\
                        </div>\
                        <div class="photomanager-workspace">\
                            <div class="photomanager-output">\
                            </div>\
                            <div class="photomanager-border-top">\
                            </div>\
                    		<div class="photomanager-border-right">\
                    		</div>\
                    		<div class="photomanager-border-bottom">\
                    		</div>\
                    		<div class="photomanager-border-left">\
                    		</div>\
                    		<div class="photomanager-cache-top">\
                    		</div>\
                    		<div class="photomanager-cache-right">\
                    		</div>\
                    		<div class="photomanager-cache-bottom">\
                    		</div>\
                    		<div class="photomanager-cache-left">\
                    		</div>\
                		    <div class="photomanager-resizer-handle">\
                		    </div>\
                		    <div class="photomanager-resizer-containment">\
                		    </div>\
                            <div class="photomanager-drag">\
                                <div class="photomanager-offset">\
                                    <img src="'+this.settings.source+'" class="photomanager-image" />\
                                </div>\
                            </div>\
                            <div class="photomanager-information">\
                                <ul class="photomanager-information-data">\
                                    <li>L : <input class="photomanager-data number photomanager-data-output-width" type="text" name="ow" value="000"></li>\
                                    <li>H : <input class="photomanager-data number photomanager-data-output-height" type="text" name="oh" value="000"></li>\
                                    <li>Image L : <input class="photomanager-data number photomanager-data-image-width" type="text" name="iw" value="000"></li>\
                                    <li>Image H : <input class="photomanager-data number photomanager-data-image-height" type="text" name="iw" value="000"></li>\
                                    <li>Offset H : <input disabled="disabled" class="photomanager-data number photomanager-data-offset-top" type="text" name="ot" value="000"></li>\
                                    <li>offset G : <input disabled="disabled" class="photomanager-data number photomanager-data-offset-left" type="text" name="ol" value="000"></li>\
                                    <li>Zoom : <input class="photomanager-data number photomanager-data-image-zoom" type="text" name="iz" value="000"></li>\
                                    <li>Background : <input class="photomanager-data photomanager-data-background-color" type="text" name="cc" value=""><div class="photomanager-preview-background-color"></div></li>\
                                </ul>\
                            </div>\
                            <div class="photomanager-slider-percent">\
                                <div class="photomanager-slider-percent-handle">\
                                </div>\
                            </div>\
                            <div class="photomanager-floating-toolbar">\
                            </div>\
                        </div><!-- end workspace -->\
                        <div class="photomanager-footer">\
                            <a \
                            href="#" \
                            class="photomanager-button photomanager-toolbar-save">\
                                <span><span class="icon disk">'+this.gettext('Save')+'</span></span>\
                            </a>\
                        </div>\
                    </div>\
                ')
				// add to document
                .appendTo(this.container);
                this.photomanager = $('#photomanager-'+ this.cntr);
                
                // closable
                if (this.settings.rules.closable == true) {
                    $('.photomanager-toolbar-close', this.photomanager).show();
                };
                // load image
                $('.photomanager-image', this.photomanager).image( 
                    this.settings.source, 
                    function() { // onload
                        // viewport size
                        _this.set_viewport();
                        // image
                        _this.set_image();
                        // zoom
                        _this.set_zoom();
                        // center offset
                        _this.center_offset();
                        // center image
                        _this.center_image();
                        // output
                        _this.set_output();
                        // cache
                        _this.set_cache();
        				// fillbox
        				_this.set_fillbox();
        				// events
        				_this.attach_events();
        				// set informations
        				_this.set_data();
        				// callback onopen
        				if (typeof _this.settings.callback.onopen == 'function') {
        				    _this.settings.callback.onopen(this.photomanager);
        				};
                    }, 
                    function() {
                        if (typeof _this.settings.callback.onloaderror == 'function') {
                            _this.settings.callback.onloaderror(this.photomanager);
                        };
                    }
                );
			},
			close: function() {
			    $('body').css({
			        'overflow': this.settings.host_overflow
			    });
			    this.photomanager.remove();
			},
			save: function() {
			    
			    if (typeof this.settings.callback.onsave == 'function') {
			        this.settings.callback.onsave(this, this.get_data());
			    };
			},
			set_viewport: function() {
			    var _this = this;
			    if (this.container[0].tagName == 'BODY') {
			        this.settings.host_overflow = $('body').css('overflow');
    			    $('body').css({
    			        'overflow': 'hidden'
    			    });
			        var container_width = $(window).width();
    			    var container_height = $(window).height();
			        this.photomanager.css({
			            'position': 'fixed',
			            'top': '0px',
			            'left': '0px'
			        });
			    } else {
			        this.container.css({
    			        'overflow': 'hidden'
    			    });
			        var container_width = this.container.width();
    			    var container_height = this.container.height();
			    }
			    this.photomanager.css({
			        'width' : container_width,
			        'height' : container_height,
			        'display' : 'block'
			    });			    
			    // workspace
			    $('.photomanager-workspace').css({
			        'height': (container_height - (60))
			    });
			},
			colorpicker: function(event, action) {
                var _this = this
                $('.photomanager-colorpicker', this.photomanager).remove();
                if (action == 'show') {
                    // show color picker
                    var colorpicker = $('<div class="photomanager-colorpicker">\
                    </div>')
                    .appendTo(this.photomanager)
                    .css({
                        left: $(event.target).position().left,
                        top: $(event.target).position().top + 25
                    })
                    .mouseleave(function() {
                        $(this).hide('fast');
                    })
                    // init farbastic
                    if ($('#farbastic-css').length == 0) {
                        $('head').append('<link id="farbastic-css" rel="stylesheet" href="'+this.settings.plugins.colorpicker.css+'" type="text/css" media="screen" charset="utf-8">');
                    };
                    if ($.farbtastic == undefined) {
                        $.getScript(this.settings.plugins.colorpicker.js, function(){
                            $('.photomanager-colorpicker', _this.photomanager)
                            .farbtastic(function() {
                                set_color(this);
                            });
                        });                        
                    } else {
                        $('.photomanager-colorpicker', this.photomanager)
                        .farbtastic(function() {
                            set_color(this);
                        });
                    }
                    var set_color = function(farbastic) {
                        $('.photomanager-preview-background-color', this.photomanager).css('background-color', farbastic.color);
                        $('.photomanager-output', this.photomanager).css('background-color', farbastic.color);
                    };
                };
            },
			get_data: function() {
			    return {
			        'output_width': $('.photomanager-output', this.photomanager).width(),
			        'output_height': $('.photomanager-output', this.photomanager).height(),
			        'image_width': $('.photomanager-image', this.photomanager).width(),
			        'image_height': $('.photomanager-image', this.photomanager).height(),
			        'offset_left': this.get_offset_left(),
			        'offset_top': this.get_offset_top(),
			        'background_color': this.rgb2hex($('.photomanager-output', this.photomanager).css('background-color'))
			    };
			},
			set_data: function(from) {
			    var _this = this;
                 // input
                $('.photomanager-data-background-color', this.photomanager).val(this.rgb2hex($('.photomanager-output', this.photomanager).css('background-color')));
                $('.photomanager-preview-background-color', this.photomanager).css('background-color', $('.photomanager-output', this.photomanager).css('background-color'))
                $('.photomanager-data-output-width', this.photomanager).val($('.photomanager-output', this.photomanager).width());
                $('.photomanager-data-output-height', this.photomanager).val($('.photomanager-output', this.photomanager).height());
                $('.photomanager-data-image-width', this.photomanager).val($('.photomanager-image', this.photomanager).width());
                $('.photomanager-data-image-height', this.photomanager).val($('.photomanager-image', this.photomanager).height());
                $('.photomanager-data-offset-top', this.photomanager).val(this.get_offset_top());
                $('.photomanager-data-offset-left', this.photomanager).val(this.get_offset_left());
                $('.photomanager-data-image-zoom', this.photomanager).val(
                    Math.round(
                        this.get_percent( 
                            this.settings.zoom_image_width, 
                            $('.photomanager-image', this.photomanager).attr('width')
                        )
                    )    
                );
                if (from != 'slider') {
                    $('.photomanager-slider-percent-handle', this.photomanager).slider(
                        'value', 
                        Math.round(
                            _this.get_percent( 
                                _this.settings.zoom_image_width, 
                                $('.photomanager-image', this.photomanager).attr('width')
                            )
                        )
                    );                    
                };
            },
            change_data: function(event) {
                var _this = this;
                var jqnode = $(event.target);
                var val = Math.round(jqnode.val());
                                
                // change output width
                if (jqnode.hasClass('photomanager-data-output-width')) {
                    if (val>0 && val<=$(window).width()) {
                        this.settings.output_width = val;
                        this.set_zoom();
                        this.set_output();
                        this.set_cache();
                    };
                }
                // change output height
                if (jqnode.hasClass('photomanager-data-output-height')) {
                    if (val>0 && val<=$(window).height()) {
                        this.settings.output_height = val;
                        this.set_zoom();
                        this.set_output();
                        this.set_cache();
                    };
                }
                // change image width
                if (jqnode.hasClass('photomanager-data-image-width')) {
                    this.resize_pixel({ 
                        width: ( val>0 ? val : this.settings.output_width)
                    });
                    this.center_image();
                }
                // change image height
                if (jqnode.hasClass('photomanager-data-image-height')) {
                    this.resize_pixel({ 
                        height: ( val>0 ? val : this.settings.output_height)
                    });
                    this.center_image();
                }
                // ofsset left
                if (jqnode.hasClass('photomanager-data-offset-top')) {
                    // console.log($('.photomanager-drag', this.photomanager).position());
                    // $('.photomanager-drag', this.photomanager).css({
                    //         'left': val
                    // })
                }
                
                // zoom
                if (jqnode.hasClass('photomanager-data-image-zoom')) {
                    if (val>0 && val<=100)
                        this.resize_percent(val);
                        this.center_image();
                        this.set_sliders();
                        this.set_floating_toolbars();
                }
                
                // background color
                if (jqnode.hasClass('photomanager-data-background-color')) {
                    $('.photomanager-output', this.photomanager).css('background-color', jqnode.val());
                };
            },
			set_image: function() {
			    // set image
                $('.photomanager-image', this.photomanager).attr(
                    'src',
                    this.settings.source + '?' + (new Date().getTime()) + '=' + (new Date().getTime())
                );
                // get original image size
                this.settings.image_width = $('.photomanager-image', this.photomanager).width();
                this.settings.image_height = $('.photomanager-image', this.photomanager).height();
                // get ratio
                this.settings.image_ratio = $('.photomanager-image', this.photomanager).width() / $('.photomanager-image', this.photomanager).height();
                
			},
			set_zoom: function() {
			    this.settings.zoom_width = (this.settings.output_width * this.settings.magnification);
			    this.settings.zoom_height = (this.settings.output_height * this.settings.magnification);
			    this.settings.zoom_image_width = (this.settings.image_width * this.settings.magnification);
                this.settings.zoom_image_height = (this.settings.image_height * this.settings.magnification);
			},
			center_offset: function() {
                $('.photomanager-drag', this.photomanager).css({
                    left: ($('.photomanager-workspace', this.photomanager).width() * 0.5),
                    top: ($('.photomanager-workspace', this.photomanager).height() * 0.5)
                });
            },
			center_image: function() {
                $('.photomanager-offset', this.photomanager).css({
                    left: 0 - ($('.photomanager-image', this.photomanager).width() * 0.5),
                    top: 0 - ($('.photomanager-image', this.photomanager).height() * 0.5)
                });
            },
			set_output: function() {
			    $('.photomanager-output', this.photomanager).css({
                    'width': this.settings.zoom_width,
                    'height': this.settings.zoom_height,
                    'background-color': this.settings.background_color,
                    'left': (($('.photomanager-workspace', this.photomanager).width() - this.settings.zoom_width) * 0.5),
                    'top': (($('.photomanager-workspace', this.photomanager).height() - this.settings.zoom_height) * 0.5)
                });
			},
			set_cache: function() {
                var border = 1;
            	var output_position = $('.photomanager-output', this.photomanager).position();
            	var workspace_position = $('.photomanager-workspace', this.photomanager).position();
                var workspace_width = $('.photomanager-workspace', this.photomanager).width()
                
            	// border top
            	$('.photomanager-border-top').css({
            	    'top': output_position.top - border,
            	    'left': output_position.left - border,
                    'width': this.settings.zoom_width + border,
                    'height': border
            	});
                // border right
                $('.photomanager-border-right').css({
            	    'top': output_position.top - border,
            	    'left': output_position.left + this.settings.zoom_width,
                    'width': border,
                    'height': this.settings.zoom_height + border
            	});
                // // border bottom
                $('.photomanager-border-bottom').css({
            	    'top': output_position.top + this.settings.zoom_height,
            	    'left': output_position.left,
                    'width': this.settings.zoom_width + border,
                    'height': border
            	});
                // // border left
                $('.photomanager-border-left').css({
            	    'top': output_position.top,
            	    'left': output_position.left - border,
                    'width': border,
                    'height': this.settings.zoom_height + border
            	});
                // cache top
                $('.photomanager-cache-top').css({
            	    top: 0,
            	    left: workspace_position.left,
            	    width: workspace_width,
            	    height: (output_position.top > 0 ? output_position.top : 0),
            	});
                // cache right
                $('.photomanager-cache-right').css({
            	    top: output_position.top,
            	    left: output_position.left + this.settings.zoom_width,
            	    width: workspace_width,
            	    height: this.settings.zoom_height,
            	});
                // cache bottom
                $('.photomanager-cache-bottom').css({
            	    top: output_position.top + this.settings.zoom_height,
            	    left: workspace_position.left,
            	    width: workspace_width,
            	    height: output_position.top,
            	});
                // // cache left
                $('.photomanager-cache-left').css({
            	    top: output_position.top,
            	    left: workspace_position.left,
            	    width: output_position.left,
            	    height: this.settings.zoom_height,
            	});
            },
            set_floating_toolbars: function() {
                var _this = this;
                // view position
                var view = $('.photomanager-output', this.photomanager).position();                
                // top
                var top = this.settings.zoom_height + view.top - 100;
                if ((top + 30) > $('.photomanager-workspace', this.photomanager).height())
                    top = $('.photomanager-workspace', this.photomanager).height() - 30;
                // left
                var left = this.settings.zoom_width + view.left + 0;
                if ((left + 30) > $('.photomanager-workspace', this.photomanager).width())
                    left = $('.photomanager-workspace', this.photomanager).width() - 30;
                // set toolbar position
                $('.photomanager-floating-toolbar', this.photomanager).css({
                    top: top,
                    left: left
                });
            },
            set_sliders: function() {
                var _this = this;
                // view position
                var view = $('.photomanager-output', this.photomanager).position();
                // slider top
                var top = this.settings.zoom_height + view.top + 20;
                if ((top + 30) > $('.photomanager-workspace', this.photomanager).height())
                    top = $('.photomanager-workspace', this.photomanager).height() - 30;
                // set slider position
                $('.photomanager-slider-percent', this.photomanager).css({
                    top: top,
                    left: ($('.photomanager-workspace', this.photomanager).width() * 0.5) - ($('.photomanager-slider-percent', this.photomanager).width() * 0.5)
                });
                // console.log(this.get_percent( this.settings.zoom_image_width, $('.photomanager-image', this.photomanager).attr('width')) + ' percent');
                // init slider
                if ($('.ui-slider').length == 0) {
                    $('.photomanager-slider-percent-handle', this.photomanager).slider({
                        value: _this.get_percent( 
                            _this.settings.zoom_image_width, 
                            $('.photomanager-image', _this.photomanager).attr('width') 
                        ),
                        slide: function(event, ui) {
                            _this.resize_percent(ui.value);
                            _this.center_image();
                            _this.set_data('slider');
                        }
                    });
                } else {
                   $('.photomanager-slider-percent-handle', this.photomanager).slider(
                       'value', 
                       _this.get_percent( _this.settings.zoom_image_width, $('.photomanager-image', _this.photomanager).attr('width'))
                   );
                }
            },
            set_resizer: function() {
                var _this = this;
                if (this.settings.rules.output_resizable == true) {
                    var resize_width = $('.photomanager-resizer-handle', this.photomanager).width();
                    var resize_height = $('.photomanager-resizer-handle', this.photomanager).height();
                    var resizer = function(node) {
                        var position = $(node).position();
                        _this.settings.zoom_width = 
                            ((position.left - ($('.photomanager-workspace', _this.photomanager).width() * .5)) * 2)
                            + (resize_height * 2);
                        _this.settings.zoom_height = 
                            ((position.top - ($('.photomanager-workspace', _this.photomanager).height() * .5)) * 2)
                            + (resize_width * 2);
                        if (
                            _this.settings.zoom_width>$('.photomanager-image', _this.photomanager).width()
                            || _this.settings.zoom_height>$('.photomanager-image', _this.photomanager).height()
                        ) {
                            // _this.set_output();                
                        };
                        _this.set_output();
                        _this.set_cache();
                        _this.set_sliders();
                        _this.set_floating_toolbars();
                        _this.set_data();       
                    };
                    // 
                    var set = function() {
                        $('.photomanager-resizer-handle', _this.photomanager).css({
                           'top': (($('.photomanager-workspace', _this.photomanager).height() * .5) + ($('.photomanager-output', _this.photomanager).height() * .5))-resize_height,
                           'left': (($('.photomanager-workspace', _this.photomanager).width() * .5) + ($('.photomanager-output', _this.photomanager).width() * .5))-resize_width
                        });
                        $('.photomanager-resizer-containment', _this.photomanager).css({
                           'top':  ($('.photomanager-workspace', _this.photomanager).height() * .5),
                           'left':  ($('.photomanager-workspace', _this.photomanager).width() * .5),
                           'width':  ($('.photomanager-workspace', _this.photomanager).width() * .5),
                           'height':  ($('.photomanager-workspace', _this.photomanager).height() * .5),               
                        });
                    }
                    //
                    $('.photomanager-resizer-handle', _this.photomanager).draggable({
                        'containment': $('.photomanager-resizer-containment', _this.photomanager),
                        'drag': function() {
                            resizer(this);
                        },
                        'stop': function() {
                            // resizer(this);
                            _this.set_sliders();
                            _this.set_floating_toolbars();
                            _this.set_data();
                        }
                    });
                	set();
                } else {
                    $('.photomanager-resizer-handle', this.photomanager).hide();
                };
            },
			set_fillbox: function() {
			    var dimensions = this.image_fill_box(
			        this.settings.zoom_image_width, 
                    this.settings.zoom_image_height,
                    this.settings.zoom_width, 
                    this.settings.zoom_height
                );
                this.resize_pixel({
                    width: dimensions.width,
                    height: dimensions.height                    
                });
                this.center_image();
                this.center_offset();
                this.set_sliders();
			},
			set_fitbox: function() {
			    var dimensions = this.image_fit_box(
			        this.settings.zoom_image_width, 
                    this.settings.zoom_image_height,
                    this.settings.zoom_width, 
                    this.settings.zoom_height
                );
                this.resize_pixel({
                    width: dimensions.width,
                    height: dimensions.height                    
                });
                this.center_image();
                this.center_offset();
                this.set_sliders();
			},
			image_fill_box: function (img_width, img_height, box_width, box_height, magnify) {
                var img_layout = ( img_height > img_width ? 'portrait' : 'landscape');
                var img_ratio = img_width / img_height;
                var box_layout = ( box_height > box_width ? 'portrait' : 'landscape');
                var box_ratio = box_width / box_height;
                var multiplier;
                // get the multiplier       
                switch(img_layout) {
                    case 'landscape':
                    if (box_layout == 'landscape') {
                        if (box_ratio > img_ratio) {
                            multiplier = box_width / img_width;
                        } else {
                            multiplier = box_height / img_height;
                        };
                    } else if(box_layout == 'portrait') {
                        multiplier = box_height / img_height;
                    };
                    break;
                case 'portrait':
                    if (box_layout == 'portrait') {
                        if (box_ratio > img_ratio) {
                            multiplier = box_width / img_width;                          
                        } else {
                            multiplier = box_height / img_height;
                        };
                    } else if (box_layout == 'landscape') {
                        multiplier = box_width / img_width;
                    };
                }
                //return the new image dimensions
                return {
                    'width': Math.round(img_width * multiplier), 
                    'height': Math.round(img_height * multiplier)   
                };
            },
            image_fit_box: function (img_width, img_height, box_width, box_height) { //Generate new image dimensions
                var img_layout = ( img_height > img_width ? 'portrait' : 'landscape');
                var img_ratio = img_width / img_height;
                var box_layout = ( box_height > box_width ? 'portrait' : 'landscape');
                var box_ratio = box_width / box_height;
                var multiplier;
                // get the multiplier       
                switch(img_layout) {
                    case 'landscape':
                    if (box_layout == 'landscape') {
                        if (box_ratio > img_ratio) {
                            multiplier = box_height / img_height;                            
                        } else {
                            multiplier = box_width / img_width;
                        };
                    } else if(box_layout == 'portrait') {
                        multiplier = box_width / img_width;
                    };
                    break;
                case 'portrait':
                    if (box_layout == 'portrait') {
                        if (box_ratio > img_ratio) {
                            multiplier = box_height / img_height;                            
                        } else {
                            multiplier = box_width / img_width;
                        };
                    } else if (box_layout == 'landscape') {
                        multiplier = box_height / img_height;
                    };
                }
                //return the new image dimensions
                return {
                    'width': Math.round(img_width * multiplier), 
                    'height': Math.round(img_height * multiplier)   
                };
            },
            resize_percent: function(percent) {
            	this.resize_pixel({
            	    width: Math.round( this.settings.zoom_image_width * ( percent / 100 ) )
            	});
            },
            resize_pixel: function (args) {
                // if width is absent
                if (!args.width)
                    args.width = (this.settings.zoom_image_width * ( this.get_width_from_height(args.height) / 100 ));
                // if width is bigger than the image
                if (args.width > this.settings.zoom_image_width)
                    args.width = this.settings.zoom_image_width;
                // if width is absent
                if (!args.height)
                    args.height = (this.settings.zoom_image_height * ( this.get_height_from_width(args.width) / 100 ));
                // if height is bigger than the image
                if (args.height > this.settings.zoom_image_height)
                    args.height = this.settings.zoom_image_height;
                                
                $('.photomanager-image', this.photomanager).css({
                    width: args.width,
                    height: args.height
                });
            },
            get_percent: function(value1, value2) {
                return (value2 / (value1 / 100));
            },
            get_output_ratio: function() {
            	return this.settings.zoom_width / this.settings.zoom_height;
            },
            get_offset_top: function() {
            	return -(
            	    parseInt($('.photomanager-output', this.photomanager).position().top 
            	    - ($('.photomanager-drag', this.photomanager).position().top + $('.photomanager-offset', this.photomanager).position().top))
            	);
            },
            get_offset_left: function() {
            	return -(
            	    parseInt($('.photomanager-output', this.photomanager).position().left 
            	    - ($('.photomanager-drag', this.photomanager).position().left + $('.photomanager-offset', this.photomanager).position().left))
            	);
            },
            get_width_from_height: function(height) {
                return (this.get_percent(this.settings.zoom_image_height, height));
            },
            get_height_from_width: function(width) {
                return (this.get_percent(this.settings.zoom_image_width, width));
            },
            rgb2hex: function(rgb) {
                rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
                if (rgb != null) {
                    function hex(x) {
                        hexDigits = new Array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
                        return isNaN(x) ? "00" : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
                    }
                    return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);            
                } else {
                    return "#000000";
                }
            },
            attach_events : function () {
			    var _this = this;
			    $(window).resize(function(){
                  _this.set_viewport();
                  _this.center_offset();
                  _this.set_output();
                  _this.set_cache();
                  _this.set_resizer();
                  _this.set_sliders();
                  _this.set_floating_toolbars();
                });
                // resizer
                this.set_resizer();
                // slider
                this.set_sliders();
                // floating bar
                this.set_floating_toolbars();
                // $('.photomanager-floating-toolbar', this.photomanager).mouseenter(function() {
                //     $(this).fadeTo('fast', 1);
                // })
                // .mouseleave(function() {
                //     $(this).fadeTo('fast', .5);
                // });
                // save
                $('.photomanager-toolbar-save', this.photomanager).click(function() {
                    _this.save();
                    return false;
                });
                // close
                $('.photomanager-toolbar-close', this.photomanager).click(function() {
                    _this.close();
                    return false;
                });
                // fillbox
                $('.photomanager-tool-fillbox', this.photomanager).click(function() {
                    _this.set_fillbox();
                    return false;
                });
                // fitbox
                $('.photomanager-tool-fitbox', this.photomanager).click(function() {
                    _this.set_fitbox();
                    return false;
                });
                // center image
                $('.photomanager-tool-center', this.photomanager).click(function() {
                    _this.center_offset();
                    _this.center_image();
                    return false;
                });
                // drag image
                $('.photomanager-drag', this.photomanager).draggable({
                    cursor: 'crosshair',
                    drag: function() {
                        _this.set_data();
                    }
                });
                // show information
                $('.photomanager-tool-information', this.photomanager).click(function() {
                    $('.photomanager-information', _this.photomanager).toggle('fast');
                    return false;                 
                });
                // colorpicker
                $('.photomanager-tool-colorpicker', this.photomanager).click(function(event) {
                    _this.colorpicker(event, 'show');
                    return false;                 
                });
                // change data
                $('.photomanager-data', this.photomanager).change( function(event) {
                   _this.change_data(event); 
                });
                $('.photomanager-data', this.photomanager).keyup( function(event) {
                    _this.change_data(event);
                });
                $('.photomanager-data', this.photomanager).blur( function() {
                    _this.set_data();
                });
                // keyboard
                $(window).keyup(function(event) {
                    if (event.target.tagName == 'INPUT') {
                        return false;
                    };
                    var increment = 1;
                    if (event.shiftKey) {
                        increment = 10;
                    };
                    if (event.keyCode == 38) {
                        $('.photomanager-drag', this.photomanager).css({
                            'top': ($('.photomanager-drag', this.photomanager).position().top - increment)
                        })                       
                    };
                    if (event.keyCode == 39) {
                        $('.photomanager-drag', this.photomanager).css({
                            'left': ($('.photomanager-drag', this.photomanager).position().left + increment)
                        })                       
                    };
                    if (event.keyCode == 37) {
                        $('.photomanager-drag', this.photomanager).css({
                            'left': ($('.photomanager-drag', this.photomanager).position().left - increment)
                        })                       
                    };

                    if (event.keyCode == 40) {
                        $('.photomanager-drag', this.photomanager).css({
                            'top': ($('.photomanager-drag', this.photomanager).position().top + increment)
                        })                       
                    };
                });
			},
			gettext: function(str) {
			    return str;
			}
		}
	};

	// instance manager
	photomanager_component.cntr = 0;
	photomanager_component.inst = {};

	photomanager_component.add_sheet = function(opts) {
	};
})(jQuery);

// simple image preloader
$.fn.image = function(src, callback, onloaderror){
    return this.each(function(){
        var i = new Image();
        i.src = src + '?' + (new Date().getTime()) + '=' + (new Date().getTime())
        i.onload = function(i) {
            callback();
        };
        i.onerror = function() {
            if (typeof onloaderror == 'function') {
                // console.log('error loading file : '+src);
                onloaderror();
            };
        }
        this.appendChild(i);
    });
}